#coding=utf-8
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, \
    QHBoxLayout, QVBoxLayout, QTreeWidget, QComboBox, \
    QTreeWidgetItem, QPushButton, QSpinBox, QMessageBox, \
    QInputDialog
from PyQt5.QtCore import QRect, Qt, pyqtSignal, QVariant
from PyQt5.QtGui import QPainter, QPen, QPalette, QBrush, QPixmap
import os
import shutil
from PIL import Image
import numpy as np
from utils import *
import importlib

class shhaoLabel(QLabel):
    x0,y0,x1,y1 = 0,0,0,0
    rectList = []
    rectL = QRect(0,0,0,0)
    flag = False
    count = 0
    region_change = pyqtSignal(int, QRect, int, int, name='regionChange')
    w, h = 1080, 1920
    def __init__(self):
        super(shhaoLabel,self).__init__()
        self.scale = 1
        self.setFixedSize(800, 800)
        self.setStyleSheet("QLabel { background-color : white; color : blue; }")

    def mousePressEvent(self, event):
        self.x0 = event.x()
        self.y0 = event.y()
        self.flag = True

    def mouseReleaseEvent(self, event):
        self.flag = False

    def mouseMoveEvent(self, event):
        if self.flag:
            self.x1 = event.x()
            self.y1 = event.y()
            if self.x1 >= self.w:
                self.x1 = self.w-1
            if self.y1 >= self.h:
                self.y1 = self.h-1
            self.update()     

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setPen(QPen(Qt.black, 2, Qt.SolidLine))
        rect = QRect(self.x0,self.y0,self.x1-self.x0, self.y1-self.y0)
        painter.drawRect(rect)
        for rectT in self.rectList:
            painter.drawRect(rectT)
        painter.setPen(QPen(Qt.red,4,Qt.SolidLine))
        rect = self.rectL
        painter.drawRect(rect)
    
    def rectShow(self, it, count):
        # print(it.data(0,Qt.UserRole))
        self.x0 = 0
        self.x1 = 0
        self.y0 = 0
        self.y1 = 0
        self.update()
        rectTmp = it.data(0,Qt.UserRole)[0]
        self.rectL = QRect((int)(rectTmp.x() / self.scale), 
                            (int)(rectTmp.y() / self.scale), 
                            (int)(rectTmp.width() / self.scale), 
                            (int)(rectTmp.height() / self.scale))
        print(it.data(0,Qt.UserRole))

    def regionAdd(self):
        if self.x0 == 0 and self.x1 == 0 and self.y0 == 0 and self.y1 == 0:
            QMessageBox.warning(self, 'warning!', 'Please draw a rectangle before confirm.')
        else:
            self.rectList.append(QRect(self.x0, self.y0, 
                                        self.x1-self.x0, self.y1-self.y0))
            rectTmp = self.rectList[self.count]
            rectRefine = QRect((int)(rectTmp.x() * self.scale), 
                                (int)(rectTmp.y() * self.scale), 
                                (int)(rectTmp.width() * self.scale), 
                                (int)(rectTmp.height() * self.scale))
            self.regionChange.emit(self.count, rectRefine, (int)(self.w*self.scale), (int)(self.h*self.scale))
            self.count += 1
    
    def wGet(self, w):
        self.w = w

    def hGet(self, h):
        self.h = h

    def resolutionChange(self):
        '''
        以1000x1000分辨率为最大显示分辨率，如果超过则按比例缩小。
        '''
        scale = 1
        if self.w > 1000:
            if self.w > self.h:
                scale = self.w / 1000
                self.w = 1000
                self.h = (int)(self.h / scale)
            else:
                scale = self.h / 1000
                self.h = 1000
                self.w = (int)(self.w / scale)
        
        if self.h > 1000:
            if self.h > self.w:
                scale = self.h / 1000
                self.h = 1000
                self.w = (int)(self.w / scale)
            else:
                scale = self.w / 1000
                self.w = 1000
                self.h = (int)(self.h / scale)
        self.scale = scale
        self.setFixedSize(self.w, self.h)
        self.update()
        #self.setStyleSheet("QLabel { background-color : white; color : blue; }")

    def backgroundSet(self, imgName):
        '''
        实时展示生成效果图
        '''
        pixmap = QPixmap(imgName)
        pixmap.scaled(self.size(), Qt.KeepAspectRatio)
        self.setScaledContents(True)
        self.setPixmap(pixmap)
        #self.setStyleSheet("background-image:url({})".format(imgName))
        self.update()


class shhaoTreeWidget(QTreeWidget):
    attr_set = pyqtSignal(dict, name='attrSet')
    backgrounChange = pyqtSignal(str, name='backgroundSet')
    def setRegionTreeWidget(self, count, rect, w, h):
        '''
        for regionNo
        '''
        t = QTreeWidgetItem()
        t.setText(0, 'region'+str(count))
        t.setData(0, Qt.UserRole, QVariant([QRect(rect)]))
        self.addTopLevelItem(t)
        self.w = w
        self.h = h

    def regionTreeWidgetAttr(self):
        self.clear()
    
        attr = QTreeWidgetItem()
        attr.setText(0,'attr')
        self.attrBox = QComboBox()
        self.attrBox.addItems(['text', 'title', 'table','image', 'formula'])
        self.attrBox.setCurrentIndex(-1)
        self.addTopLevelItem(attr)
        self.setItemWidget(attr,1,self.attrBox)
        self.attrBox.currentTextChanged.connect(self.attrChoose)

    def attrChoose(self, attr):
        if attr == 'text' or attr == 'table' or attr == 'title':
            self.textAndTable()
        elif attr == 'image' or attr == 'formula':
            self.imageAndFormula

    def textAndTable(self):
        for i in range(1,self.topLevelItemCount()):
            self.takeTopLevelItem(1)
        t = QTreeWidgetItem()
        t.setText(0,'语言')
        self.box = QComboBox()
        self.box.addItems(['en','ch'])
        self.addTopLevelItem(t)
        self.setItemWidget(t,1,self.box)

        lineSpacing = QTreeWidgetItem()
        lineSpacing.setText(0,'lineSpacing')
        self.lineBox = QSpinBox()
        self.lineBox.setValue(0)
        self.lineBox.setRange(0,10)
        self.addTopLevelItem(lineSpacing)
        self.setItemWidget(lineSpacing,1,self.lineBox)

        paraSpacing = QTreeWidgetItem()
        paraSpacing.setText(0,'paraSpacing')
        self.paraBox = QSpinBox()
        self.paraBox.setValue(0)
        self.paraBox.setRange(0,100)
        self.addTopLevelItem(paraSpacing)
        self.setItemWidget(paraSpacing,1,self.paraBox)

        blank = QTreeWidgetItem()
        blank.setText(0,'blank')
        self.blankBox = QSpinBox()
        self.blankBox.setValue(20)
        self.blankBox.setRange(20,50)
        self.addTopLevelItem(blank)
        self.setItemWidget(blank,1,self.blankBox)

    def imageAndFormula(self):
        for i in range(1,self.topLevelItemCount()):
            self.takeTopLevelItem(1)

    def attrDataGet(self):
        attr = {}
        attr['attr'] = self.attrBox.currentText()
        if attr['attr'] == 'text' or attr['attr'] == 'table' or attr['attr'] == 'title':
            attr['lan'] = self.box.currentText()
            attr['lineSpacing'] = self.lineBox.value()
            attr['paraSpacing'] = self.paraBox.value()
            attr['blank'] = self.blankBox.value()
        
        self.attrSet.emit(attr)


    def attrDataSet(self, attr):
        '''
        for regionNo
        '''
        # t = self.topLevelItem(self.count)
        t = self.click_item
        rect = t.data(0, Qt.UserRole)[0]
        t.setData(0, Qt.UserRole, QVariant([rect, attr]))

    def getCount(self, it, count):
        self.count = count
        self.click_item = it

    def ConfigGen(self):
        defaultConfig = './config.default'
        target = './config.py'
        if os.path.exists(target):
            os.remove(target)
        shutil.copy(defaultConfig, target)
        # with open(target, 'a') as f:
        f = open(target, 'a')
        f.write('picWidth = {}\n'.format(self.w))
        f.write('picHeight = {}\n'.format(self.h))
        print(self.topLevelItemCount())
        regionList = []
        for i in range(self.topLevelItemCount()):
            print(i, self.topLevelItem(i).data(0,Qt.UserRole))
            f.write(str(self.topLevelItem(i).text(0)) + '=')
            rect = self.topLevelItem(i).data(0,Qt.UserRole)[0]
            tempDict = self.topLevelItem(i).data(0,Qt.UserRole)[1]
            # print (rect.x(), rect.y(), rect.width(), rect.height())
            tempDict['name'] = str(self.topLevelItem(i).text(0))
            tempDict['x'] = rect.x()
            tempDict['y'] = rect.y()
            tempDict['h'] = rect.height()
            tempDict['w'] = rect.width()
            f.write(str(tempDict) + '\n')
            regionList.append(tempDict)
        f.write('regionList = {}\n'.format(regionList))
        f.write('numRegion = {}\n'.format(self.topLevelItemCount()))
        f.close()
        # import config
        importlib.reload(config)
        surface = np.full((config.picHeight, config.picWidth, 3), 255,dtype=np.ubyte)
        print("numRigion = {}".format(config.numRegion))
        for i in range(config.numRegion):
            fontCls = FontClass(config.regionList[i], surface)
            surface = fontCls.render()

        im = Image.fromarray(surface)
        im.save(config.outFileName)
        self.backgroundSet.emit(config.outFileName)

class shhaoWidget(QWidget):
    def __init__(self):
        super(shhaoWidget, self).__init__()
        self.setWindowTitle('hello')
        w = shhaoLabel()
        regionNo = shhaoTreeWidget()
        regionNo.setHeaderLabel('区域')
        regionNo.header().setDefaultAlignment(Qt.AlignCenter)
        w.regionChange.connect(regionNo.setRegionTreeWidget)
        regionNo.itemClicked.connect(w.rectShow)

        ###  resolution change layout  ###
        widthLabel = QLabel()
        heightLabel = QLabel()
        widthLabel.setText('width')
        heightLabel.setText('height')
        widthBox = QSpinBox()
        heightBox = QSpinBox()
        widthBox.setRange(500,4000)
        heightBox.setRange(500,4000)
        widthBox.setValue(1080)
        heightBox.setValue(1920)
        retinaChangeButton = QPushButton('change resolution')
        widthLayout = QHBoxLayout()
        heightLayout = QHBoxLayout()
        widthLayout.addWidget(widthLabel, 1)
        widthLayout.addWidget(widthBox, 1)
        heightLayout.addWidget(heightLabel, 1)
        heightLayout.addWidget(heightBox, 1)

        widthBox.valueChanged.connect(w.wGet)
        heightBox.valueChanged.connect(w.hGet)
        retinaChangeButton.clicked.connect(w.resolutionChange)
        retinaChangeButton.clicked.connect(self.repaint)

        ### button set ###
        confirmButton = QPushButton('confirm')
        setAttrButton  = QPushButton('setAttr')
        confirmAttrButton = QPushButton('attr confirm')
        confirmButton.clicked.connect(w.regionAdd)
        genButton = QPushButton('sampleGen')
        genButton.clicked.connect(regionNo.ConfigGen)
        regionNo.backgroundSet.connect(w.backgroundSet)

        ### attr set ###
        attrList = shhaoTreeWidget()
        attrList.setColumnCount(2)
        attrList.setHeaderLabels(["属性","值"])
        attrList.header().setDefaultAlignment(Qt.AlignCenter)
        attrList.expandAll()
        setAttrButton.clicked.connect(attrList.regionTreeWidgetAttr)
        confirmButton.clicked.connect(attrList.clear)
        confirmAttrButton.clicked.connect(attrList.attrDataGet)
        regionNo.itemClicked.connect(regionNo.getCount)
        attrList.attrSet.connect(regionNo.attrDataSet)

        ###  layout set  ###
        self.n = QHBoxLayout()
        v = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(confirmButton)
        buttonLayout.addWidget(setAttrButton)
        v.addLayout(widthLayout)
        v.addLayout(heightLayout)
        v.addWidget(retinaChangeButton)
        v.addLayout(buttonLayout)
        v.addWidget(regionNo)
        v.addWidget(attrList)
        v.addWidget(confirmAttrButton)
        v.addWidget(genButton)
        self.n.addWidget(w)
        self.n.addLayout(v)
        # self.showFullScreen()
        self.setLayout(self.n)


if __name__ == '__main__':
    app = QApplication(sys.argv)  # 创建一个应用
    window = shhaoWidget()  # 在这个应用条件下创建一个窗口
    window.show()
    
    sys.exit(app.exec_())  # 将app的退出信号传给程序进程，让程序进程退出